<?php

/**
 * Ignus Framework
 *
 * @author Sergey Palyanov <sergey.palyanov@gmail.com>
 * @link http://code.google.com/p/ignus-php/
 * @license http://apache.org/licenses/LICENSE-2.0
 * @package Ignus
 * @subpackage App
 * @since 0.1
 */

namespace Ignus;

/**
 * @package Ignus
 * @subpackage App
 * @since 0.2
 */
abstract class Localize
{
    /**
     * @var string Localization language
     */
    private static $localization;

    /**
     * @var array Loaded localization messages
     */
    private static $messages = array();

    /**
     * @param array $localizations
     * @static
     * @return void
     */
    public static function init(array $localizations)
    {
        if (($lang = Http::getCookie('ignus_lang')) != null) {
            self::$localization = $lang;
            return;
        }

        if (count($localizations) == 1) {
            Http::setCookie('ignus_lang', $localizations[0]);
            self::$localization = $localizations[0];
            return;
        }

        // default acceptable language is the localization with highest priority
        self::$localization = $localizations[0];

        $languages = Http::getLanguages();
        foreach ($languages as $lang) {
            if ($lang == '*') break;
            if (array_search($lang, $localizations) !== false) {
                self::$localization = $lang;
                break;
            }
        }
    }

    /**
     * Loads and caches localization messages file of specified Request language
     * @static
     * @param string $base Messages file base name (without language and extension)
     * @return void
     */
    private static function loadFile($base)
    {
        $filename = App::getPath('data', $base . '.' . self::$localization . '.php');

        if (!(App::isProduction() && file_exists($filename))) {
            $source = App::getPath('lang', $base . '.' . self::$localization . '.ini');
            if (!file_exists($source))
                throw new \RuntimeException("Localization source file '$source' does not exists");

            $messages = parse_ini_file($source, false);
            if ($messages === false)
                throw new \RuntimeException("Error parsing language file '$source'");

            $lines[] = '<?php ';
            $lines[] = 'self::$messages[\''.$base.'\'] = ' . var_export($messages, true).';';

            if (file_put_contents($filename, $lines, LOCK_EX) === false)
                throw new \RuntimeException("Error writing cache localization file '$filename'");
        }

        require_once $filename;
    }

    /**
     * Fetch and return localized
     * @static
     * @param string $file Messages file base name (without language and extension)
     * @param string $key Message key
     * @return string|array
     */
    public static function get($file, $key)
    {
        if (!isset(self::$messages[$file]))
            self::loadFile($file);

        return isset(self::$messages[$file][$key]) ? self::$messages[$file][$key] : $key;
    }

    /**
     * Return localized message formatted with optional arguments.
     * If localized message is an array, method returns it as is.
     * @param string $file Messages file base name (without language and extension)
     * @param string $key Message key
     * @return string|array Localized message
     */
    public static function format($file, $key)
    {
        $message = self::get($file, $key);

        switch (true) {
            case $message == $key:
            case func_num_args() == 2:
            case is_array($message):
                return $message;
        }

        return vsprintf($message, array_slice(func_get_args(), 2));
    }

    /**
     * Return localized message with replaced parts
     * @static
     * @param string $file Messages file base name (without language and extension)
     * @param string $key Message key
     * @param array $replaces Replacements array of $from => $to
     * @return string|array Localized message
     * @since 0.5.2
     */
    public static function replace($file, $key, array $replaces)
    {
        $message = self::get($file, $key);
        if ($message == $key)
            return $message;

        if (is_array($message)) {
            foreach ($message as &$element)
                $element = strtr($element, $replaces);
            return $message;
        }

        return strtr($message, $replaces);
    }
}
